﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using OCR.Digital;
using OCR.Digital.Comm;

namespace OCR.Digital.Main
{
    public partial class Form1 : Form
    {
        #region 【事件相关】
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            lbMsg.Text = "";
            //tbImgUrl.Text = "http://127.0.0.1:9000/222.jpg";
            tbImgUrl.Text = "http://www.gz.gov.cn/sofpro/gecs/common/image.jsp";
            // tbImgUrl.Text = "http://daoyou-chaxun.cnta.gov.cn/single_info/validatecode.asp";
        }
        private void pbSource_Click(object sender, EventArgs e)
        {
            LoadImageAndAnalyze();
        }

        private void btnFlush_Click(object sender, EventArgs e)
        {
            LoadImageAndAnalyze();
        }
        #endregion

        private Bitmap LoadSourceImage()
        {
            var url = tbImgUrl.Text.Trim();
            var request = WebRequest.Create(url);
            var response = request.GetResponse();
            var stream = response.GetResponseStream();
            var bitmap = (Bitmap)Bitmap.FromStream(stream);
            pbSource.Image = bitmap;
            pbSource.Width = bitmap.Width;
            pbSource.Height = bitmap.Height;
            return bitmap;
        }
        private void LoadImageAndAnalyze()
        {
            tb1.Text = "";
            tb2.Text = "";
            tb3.Text = "";
            tb4.Text = "";
            lbMsg.Text = "";
            //根据URL加载原始图
            Bitmap bitmap = LoadSourceImage();
            Bitmap bm = (Bitmap)bitmap.Clone();
            //灰度化
            BitmapHandle bh = new BitmapHandle(bm);
            Bitmap bmHuidu = (Bitmap)bh.GrayByPixels().Clone();
            pgHuidu.Image = bmHuidu;
            pgHuidu.Width = bmHuidu.Width;
            pgHuidu.Height = bmHuidu.Height;
            //去噪
            Bitmap bmQuzao = (Bitmap)bh.ClearNoise(128, 1).Clone();
            pgQuzao.Image = bmQuzao;
            pgQuzao.Width = bmQuzao.Width;
            pgQuzao.Height = bmQuzao.Height;
            //灰度二值化,使图片变成2中颜色（黑/白色）
            Bitmap bmHuier = (Bitmap)bh.ConvertPixels().Clone();
            pgHuier.Image = bmHuier;
            pgHuier.Width = bmHuier.Width;
            pgHuier.Height = bmHuier.Height;
            //扭曲修正
            //Bitmap bmNiuqu = bh.ReSetBitMap();
            //裁剪多余空位
            //bmNiuqu = bh.Cut(bmNiuqu, 5, 0, bmNiuqu.Width - 5, bmNiuqu.Height - 5);
            Bitmap bmNiuqu = (Bitmap)bh.CutBitMap().Clone();
            pgNiuqu.Image = bmNiuqu;
            pgNiuqu.Width = bmNiuqu.Width;
            pgNiuqu.Height = bmNiuqu.Height;
            //切割图片
            List<Bitmap> bms = bh.SplitBitMap();
            gbPic.Controls.Clear();
            for (int i = 0; i < bms.Count; i++)
            {
                PictureBox pb = new PictureBox();
                pb.Name = "pic" + i.ToString();
                pb.Image = bms[i];
                pb.Width = bms[i].Width;
                pb.Height = bms[i].Height;
                //边框事件，暂时无用
                pb.Paint += Pb_Paint1;
                //设置位置
                pb.Location = new Point((18 * i + 10), 20);
                //设置一个边框
                pb.BorderStyle = BorderStyle.FixedSingle;

                pb.Click += Pb_Click;
                gbPic.Controls.Add(pb);
            }
            //Bitmap[] arrmap = SplitImg(bmNiuqu, 4, 1);
            ////显示切割图片
            //DisplaySplitImg(arrmap);

            //计算二值化代码
            //tbCode.Text = GetAllCode(arrmap);
            tbCode.Text = GetAllCode(bms.ToArray());

            //解析出数字
            StringBuilder sb = new StringBuilder();
            StringBuilder sb2 = new StringBuilder();
            string[] arrv = tbCode.Text.Split(new string[] { "=======" }, StringSplitOptions.RemoveEmptyEntries);

            foreach (var t in arrv)
            {
                Console.WriteLine(t);
                sb.Append(new Compar(t).GetCode());
                sb2.Append(new Compar(t).GetCode2());
            }
            txtShuzi.Text = sb.ToString();
            txtShuzi2.Text = sb2.ToString();
        }

        private void Pb_Click(object sender, EventArgs e)
        {
            PictureBox pb = (PictureBox)sender;
            Bitmap bm = (Bitmap)pb.Image;
            StringBuilder sb = new StringBuilder();
            int i, j = 0;
            for (i = 0; i < bm.Height; i++)
            {
                for (j = 0; j < bm.Width; j++)
                {
                    int r = bm.GetPixel(j, i).R;
                    //128的灰度参考值
                    sb.Append(r < 100 ? "  ■  " : "      ");   //■□
                    //sb.Append(r < 100 ? "  ■  " : "  □  ");   //■□
                }
                sb.Append("\r\n");
            }
            sb.Insert(0, string.Format("行：{0}，列：{1}，比率：{2}\r\n", i, j, i * 1.0d / j));
            MessageBox.Show(sb.ToString());
        }

        private void Pb_Paint1(object sender, PaintEventArgs e)
        {
            //            PictureBox p = (PictureBox)sender;
            //            Pen pp = new Pen(Color.White);
            //            e.Graphics.DrawRectangle(pp, e.ClipRectangle.X, e.ClipRectangle.Y,
            // e.ClipRectangle.X + e.ClipRectangle.Width - 1,
            //e.ClipRectangle.Y + e.ClipRectangle.Height - 1);
        }


        private void Pb_Paint(object sender, PaintEventArgs e)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// 根据图片获取特征码
        /// </summary>
        /// <param name="arrmap"></param>
        /// <returns></returns>
        private string GetAllCode(Bitmap[] arrmap)
        {
            StringBuilder code = new StringBuilder();
            string spchar = "=======";
            for (int i = 0; i < arrmap.Length; i++)
            {
                if (i == arrmap.Length - 1)
                {
                    spchar = string.Empty;
                }
                code.Append(GetCodebyBitmap(arrmap[i]) + spchar);
            }
            return code.ToString();
        }
        /// <summary>
        /// 根据图片获取特征码
        /// </summary>
        /// <param name="bitmap">图片</param>
        /// <returns></returns>
        private string GetCodebyBitmap(Bitmap bitmap)
        {
            var code = new StringBuilder();
            for (var i = 0; i < bitmap.Width; i++)
            {
                for (var j = 0; j < bitmap.Height; j++)
                {
                    int r = bitmap.GetPixel(i, j).R;
                    //128的灰度参考值
                    code.Append(r < 100 ? "1" : "0");
                }
            }
            return code.ToString();
        }

        #region 【特征码入库保存动作】
        private void button1_Click(object sender, EventArgs e)
        {
            var v1 = tb1.Text.Trim();
            var v2 = tb2.Text.Trim();
            var v3 = tb3.Text.Trim();
            var v4 = tb4.Text.Trim();
            var codes = tbCode.Text.Split(new string[] { "=======" }, StringSplitOptions.RemoveEmptyEntries);
            if (!string.IsNullOrEmpty(v1) && codes.Length >= 1)
                WriteFile(v1, codes[0]);
            if (!string.IsNullOrEmpty(v2) && codes.Length >= 2)
                WriteFile(v2, codes[1]);
            if (!string.IsNullOrEmpty(v3) && codes.Length >= 3)
                WriteFile(v3, codes[2]);
            if (!string.IsNullOrEmpty(v4) && codes.Length >= 4)
                WriteFile(v4, codes[3]);
            lbMsg.Text = "ok";
        }
        /// <summary>
        /// 特征码入库，简单的搞了一个文本文件当做数据库
        /// </summary>
        /// <param name="value">值</param>
        /// <param name="code">二值码</param>
        private void WriteFile(string value, string code)
        {
            var path = Regex.Replace(Environment.CurrentDirectory, @"\\bin\\Debug", "") + "\\code.txt";
            Console.WriteLine("pat:" + path);
            using (var sw = new StreamWriter(path, true))
            {
                sw.WriteLine($"{value}:{code}");
            }
        }
        #endregion

        private void label11_Click(object sender, EventArgs e)
        {

        }
    }
}
